package gov.pbc.nn.kjgl.software.view;

import gov.pbc.nn.core.bdf.service.DeptService;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.GetTableUtils;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.entity.Project;
import gov.pbc.nn.kjgl.software.dao.KjkShDao;
import gov.pbc.nn.kjgl.software.dao.KjkShJdbcDao;
import gov.pbc.nn.uflo.entity.Opinion;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.ProcessService;
import com.bstek.uflo.service.TaskOpinion;

@Component
public class KjkShPR {

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	@Autowired
	private ProcessService processService;

	@Autowired
	private KjkShDao kjkShDao;

	@Autowired
	private KjkShJdbcDao kjkShJdbcDao;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;

	@Autowired
	private DeptService deptService;

	@DataProvider
	public Project loadProject(String id) {
		return kjkShJdbcDao.loadProject(id);
	}

	@DataProvider
	public List<Map<String, Object>> getAll() {
		String deptId = ContextHolder.getLoginUser().getDepts().get(0).getId();
		List<IUser> users = SecurityUtils.getUserByRoleForZZ(deptId,Constants.ROLE_HLD);
		List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
		if (users.size() > 0) {
			for (IUser u : users) {
				List<IDept> lsDept = deptService.loadUserDepts(u.getUsername());
				if (lsDept.size() > 0) {
					IDept dept = lsDept.get(0);
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("cname", u.getCname());
					map.put("username", u.getUsername());
					map.put("dept", dept.getName());
					ls.add(map);
				}
			}
		} else {
			ls = null;
		}
		return ls;
	}

	/**
	 * 科技科给行领导审批
	 * 
	 * @param opinion
	 * @param taskId
	 */

	@Expose
	@Transactional
	public void KjkSpToHld(String opinion, String taskId, String zgkjhldUser, String zgywhldUser, String declareMeans) {
		// 1.是申请人刚刚立项的或者回退之后重新申请给科技行领导的
		// 4. 保存意见
		taskClient.start(Long.valueOf(taskId));
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		TaskOpinion taskOpinion = new TaskOpinion(opinion);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("zgkjhld", zgkjhldUser);// 主管科技行领导（流程变量）
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());// 业务表ID值
		o.setBusTable("T_PROJECT");// 业务表表名称
		if ("1".equals(declareMeans)) {
			o.setProcessName("集中式立项申请");
		} else {
			o.setProcessName("非集中式立项申请");
			map.put("zgywhld", zgywhldUser);// 主管业务行领导（流程变量）
		}
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setTaskName(task.getTaskName());
		o.setTaskId(Long.parseLong(taskId));
		o.setOpinion(opinion);
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		taskClient.complete(Long.valueOf(taskId), "to 主管科技行领导审核", map, taskOpinion);
	}

	/**
	 * 线下保存意见
	 */
	@Expose
	@Transactional
	public void saveCsYj(String taskId, String opinion, Project project, String zgkjhldUser, String declareMeans) {
		// 线下 的时候 科技科选择行领导，保存 行领导的 username(zgkjhld 流程变量)
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("zgkjhld", zgkjhldUser);
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		long processInstanceId = task.getProcessInstanceId();
		processService.saveProcessVariables(processInstanceId, map);
		// 保存初审意见
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());// 业务表ID值
		o.setBusTable("T_PROJECT");// 业务表表名称
		if ("1".equals(declareMeans)) {
			o.setProcessName("集中式立项申请");
		} else {
			o.setProcessName("非集中式立项申请");
		}
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setTaskName(task.getTaskName());
		o.setTaskId(Long.parseLong(taskId));
		o.setOpinion(opinion);
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		project.setState(66);
		this.kjkShDao.update(project);
	}

	/**
	 * 行领导审核后 如果同意 则 科技科给科技处审批
	 * 
	 * 
	 * @param opinion
	 * @param taskId
	 */
	@Expose
	@Transactional
	public void KjkSpToKjc(String taskId, String opinion) {
		// 2.已经通过行领导审核 给 科技处的
		// 4. 保存意见
		// 5.同意 state =7
		taskClient.start(Long.valueOf(taskId));
		TaskOpinion taskOpinion = new TaskOpinion(opinion);
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setBusTable("T_PROJECT");
		o.setProcessName("集中式立项申请");
		o.setNodeName(task.getNodeName());
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setTaskName(task.getTaskName());
		o.setTaskId(Long.parseLong(taskId));
		o.setOpinion(opinion);
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", "7");
		taskClient.complete(Long.valueOf(taskId), "to 科技处", map, taskOpinion);
	}

	/**
	 * 科技科给退回申请人
	 *
	 * @param opinion
	 * @param taskId
	 */
	@Expose
	@Transactional
	public void KjkSpToSqr(String taskId, String declareMeans, String opinion, Project project) {
		// 3.是领导审核之后退回来的。如果不通过退回给申请人。
		// 4.保存意见
		// 5.申请人立项 state 为2。退给申请人 state=4
		taskClient.start(Long.valueOf(taskId));
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		TaskOpinion taskOpinion = new TaskOpinion(opinion);
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setBusTable("T_PROJECT");
		if ("1".equals(declareMeans)) {
			o.setProcessName("集中式立项申请");
		} else {
			o.setProcessName("非集中式立项申请");
		}
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setTaskName(task.getTaskName());
		o.setTaskId(Long.parseLong(taskId));
		o.setOpinion(opinion);
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		project.setState(5);
		this.kjkShDao.update(project);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", "4");
		taskClient.complete(Long.valueOf(taskId), "退回", map, taskOpinion);

	}

	/**
	 * 非集中
	 * 
	 * @return
	 */

	@Expose
	@Transactional
	public void KjkSpToSqrQd(String taskId, String opinion) {
		// 非集中 确定可以通过，回退给申请人。
		// 改变状态 state = 12
		taskClient.start(Long.valueOf(taskId));
		TaskOpinion taskOpinion = new TaskOpinion(opinion);
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setBusTable("T_PROJECT");
		o.setProcessName("非集中式立项申请");
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setTaskName(task.getTaskName());
		o.setTaskId(Long.parseLong(taskId));
		o.setOpinion(opinion);
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", "12");
		taskClient.complete(Long.valueOf(taskId), "退回", map, taskOpinion);
	}

	/**
	 * 集中式申报 当 申请人 立项时：return state = 2 当 科技行领导 同意 通过时 ： return state =5
	 * 当科技行领导不同意 通过时： return state =6 前台根据返回的state 显示按钮。
	 * 
	 * @param processInstanceId
	 * @return
	 */

	@Expose
	public int getStateJZ(String processInstanceId) {
		ProcessInstance process = processClient.getProcessInstanceById(Long.valueOf(processInstanceId));
		String processVariable = processClient.getProcessVariable("state", process).toString();
		if (processVariable.equals("2")) {
			return 2;
		} else if (processVariable.equals("5")) {
			return 5;
		}
		return 6;
	}

	/**
	 * 上传主管科技行领导签字文件
	 * 
	 * @param file
	 * @param params
	 * @throws IOException
	 */
	@FileResolver
	public String uploadSign(UploadFile file, Map<String, Object> params) throws IOException {
		String businessId = (String) params.get("businessId");
		String declareMeans = (String) params.get("declareMeans");
		String id = (String) params.get("id");
		long taskId = Long.parseLong(params.get("taskId").toString());
		Task task = this.taskClient.getTask(taskId);
		long processInstanceId = task.getProcessInstanceId();
		ProcessInstance process = processClient.getProcessInstanceById(Long.valueOf(processInstanceId));
		// 取得流程变量 zgkjhld 行领导的username(线下保存已经的时候 会保存这个流程变量)
		String username = processClient.getProcessVariable("zgkjhld", process).toString();
		Map<String, Object> ps = new HashMap<String, Object>();
		ps.put("taskId", taskId);
		ps.put("username", username);
		String hql = "from " + Opinion.class.getName() + " where taskId=:taskId and username=:username";
		List<Opinion> list = this.coreHibernateDao.query(hql, ps);
		// 判断行领导是否有审批过，如果没有则保存，否则更新意见
		if (list.isEmpty()) {
			final Opinion o = new Opinion();
			o.setBusKey(businessId);
			o.setBusTable(GetTableUtils.getTablename(Project.class));
			o.setTaskId(taskId);
			o.setTaskName(task.getTaskName());
			o.setNodeName(task.getNodeName());
			if ("1".equals(declareMeans)) {
				o.setProcessName("集中式立项申请");
			} else {
				o.setProcessName("非集中式立项申请");
			}
			o.setProcessInstanceId(task.getProcessInstanceId());
			o.setUsername(username);// 领导username
			o.setCname((String) kjkShJdbcDao.getHld(username).get(0).get("Cname"));// 领导中文名
			o.setDeptId((String) kjkShJdbcDao.getHld(username).get(0).get("deptId"));
			o.setDeptName((String) kjkShJdbcDao.getHld(username).get(0).get("name"));
			byte[] bytes = FileCopyUtils.copyToByteArray(file.getInputStream());

			o.setOpinionImg(bytes);
			this.coreHibernateDao.save(o);

			updateProjectById(id);
			// 返回图片
			String sign = Base64.encodeBase64String(bytes);
			sign = "data:image/jpg;base64," + sign;
			return sign;
		} else {
			final Opinion o = list.get(0);
			byte[] bytes = FileCopyUtils.copyToByteArray(file.getInputStream());
			o.setOpinionImg(bytes);
			this.coreHibernateDao.update(o);
			updateProjectById(id);

			String sign = Base64.encodeBase64String(bytes);
			sign = "data:image/jpg;base64," + sign;
			return sign;
		}
	}

	/**
	 * 上传主管业务行领导签字文件
	 * 
	 * @param file
	 * @param params
	 * @throws IOException
	 */
	@FileResolver
	@Transactional
	public String uploadYwSign(UploadFile file, Map<String, Object> params) throws IOException {
		String businessId = (String) params.get("businessId");
		String id = (String) params.get("id");
		long taskId = Long.parseLong(params.get("taskId").toString());
		Task task = this.taskClient.getTask(taskId);
		// long processInstanceId = task.getProcessInstanceId();
		// ProcessInstance process =
		// processClient.getProcessInstanceById(Long.valueOf(processInstanceId));
		// // 取得流程变量 zgywhld 行领导的username (立项提交到科技科 的时候会保存这个流程变量，因为不是科技科选择的)
		// String username = processClient.getProcessVariable("zgywhld",
		// process).toString();
		// 取得业务主管的username，查询
		String username = (String) params.get("username");
		Map<String, Object> ps = new HashMap<String, Object>();
		ps.put("taskId", taskId);
		ps.put("username", username);
		String hql = "from " + Opinion.class.getName() + " where taskId=:taskId and username=:username";
		List<Opinion> list = this.coreHibernateDao.query(hql, ps);
		// 判断行领导是否有审批过，如果没有则保存，否则跟新
		if (list.isEmpty()) {
			final Opinion o = new Opinion();
			o.setBusKey(businessId);
			o.setBusTable(GetTableUtils.getTablename(Project.class));
			o.setTaskId(taskId);
			o.setTaskName(task.getTaskName());
			o.setProcessName("非集中式立项申请");
			o.setNodeName(task.getNodeName());
			o.setUsername(username);// 领导username
			o.setProcessInstanceId(task.getProcessInstanceId());
			o.setCname((String) kjkShJdbcDao.getHld(username).get(0).get("Cname"));// 领导中文名
			o.setDeptId((String) kjkShJdbcDao.getHld(username).get(0).get("deptId"));
			o.setDeptName((String) kjkShJdbcDao.getHld(username).get(0).get("name"));
			byte[] bytes = FileCopyUtils.copyToByteArray(file.getInputStream());
			o.setOpinionImg(bytes);
			this.coreHibernateDao.save(o);
			updateProjectStateById(id);

			String sign = Base64.encodeBase64String(bytes);
			sign = "data:image/jpg;base64," + sign;
			return sign;

		} else {
			final Opinion o = list.get(0);
			byte[] bytes = FileCopyUtils.copyToByteArray(file.getInputStream());
			o.setOpinionImg(bytes);
			// this.kjkShDao.update(o);
			this.coreHibernateDao.update(o);
			updateProjectStateById(id);

			String sign = Base64.encodeBase64String(bytes);
			sign = "data:image/jpg;base64," + sign;
			return sign;
		}
	}

	private void updateProjectById(String id) {// 上传主管科技行领导签字文件修改状态，控制按钮（报南宁中支）
		String hql = "from Project where invalid=false and id=:id ";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		Project project = (Project) this.kjkShDao.query(hql, map).get(0);
		project.setState(44);
		this.kjkShDao.update(project);
	}

	private void updateProjectStateById(String id) {// 上传主管业务行领导签字文件修改状态，控制按钮（同意申报）
		String hql = "from Project where invalid=false and id=:id ";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		Project project = (Project) this.kjkShDao.query(hql, map).get(0);
		project.setState(43);
		this.kjkShDao.update(project);
	}

	@Expose
	public String[] getOpinionSign(String businessId, String processInstanceId, String taskId, String username)
			throws Exception {
		return this.kjkShDao.getOpinionSign(businessId, processInstanceId, taskId, username);
	}

}
